package com.smartleanx.module.hrm.app.empRisk;

import cn.hutool.core.collection.CollUtil;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.module.hrm.dal.dataobject.companysystem.CompanySystemDO;
import com.smartleanx.module.hrm.dal.dataobject.companysystem.CompanySystemDeptDO;
import com.smartleanx.module.hrm.dal.dataobject.companysystememployee.CompanySystemEmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.risk.RiskTypeDO;
import com.smartleanx.module.hrm.enums.ErrorCodeConstants;
import com.smartleanx.module.hrm.eums.employee.EmployeeStatusEnum;
import com.smartleanx.module.hrm.eums.risk.RiskLevelEnum;
import com.smartleanx.module.hrm.eums.risk.RiskTypeEnum;
import com.smartleanx.module.hrm.service.companysystem.CompanySystemDeptService;
import com.smartleanx.module.hrm.service.companysystem.CompanySystemService;
import com.smartleanx.module.hrm.service.companysystememployee.CompanySystemEmployeeService;
import com.smartleanx.module.hrm.service.employee.EmployeeService;
import com.smartleanx.module.hrm.service.risk.RiskService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 规章制度是否向员工告知
 *
 * @author tengcj
 * @since 2024/6/27
 */
@Component
public class RiskEmpRegulationHandleService implements EmployeeRiskHandle {

    public static final long RISK_ID = RiskTypeEnum.REGULATION_NOT_INFORM.getCode();

    @Resource
    private RiskService riskService;

    @Resource
    private EmployeeService employeeService;

    @Resource
    private CompanySystemService companySystemService;

    @Resource
    private CompanySystemEmployeeService companySystemEmployeeService;

    @Resource
    private CompanySystemDeptService companySystemDeptService;

    @Override
    public Long type() {
        return RISK_ID;
    }

    @Override
    public void handleEmployeeRisk(Set<Long> employeeIds) {
        List<EmployeeDO> employeeList = employeeService.getEmployeeList(employeeIds);
        if (CollUtil.isEmpty(employeeList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }
        RiskTypeDO riskType = riskService.getRiskType(RISK_ID);
        if (riskType == null) {
            throw exception(ErrorCodeConstants.RISK_TYPE_NOT_EXISTS);
        }

        List<CompanySystemDeptDO> list = companySystemDeptService.getListByDeptId(
                employeeList.stream().map(EmployeeDO::getDeptId).collect(Collectors.toSet())
        );
        if (CollUtil.isNotEmpty(list)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }

        List<CompanySystemDO> companySystemList = companySystemService.getCompanySystemList(
                list.stream().map(CompanySystemDeptDO::getCompanySystemId).collect(Collectors.toSet()), null
        );
        if (CollUtil.isEmpty(companySystemList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }

        Map<Long, List<CompanySystemEmployeeDO>> employeeLearnedMap = CollectionUtils.convertMultiMap(
                companySystemEmployeeService.getListByEmployeeId(employeeIds), CompanySystemEmployeeDO::getEmployeeId
        );

        for (EmployeeDO employeeDO : employeeList) {
            if (EmployeeStatusEnum.SEPARATED.getCode().equals(employeeDO.getState())
                    || EmployeeStatusEnum.TO_BE_SEPARATED.getCode().equals(employeeDO.getState())) {
                continue;
            }
            List<CompanySystemEmployeeDO> companyLearnedList = employeeLearnedMap.get(employeeDO.getId());
            Set<Long> idSet = CollectionUtils.convertSet(companyLearnedList, CompanySystemEmployeeDO::getCompanySystemId);
            for (CompanySystemDO companySystemDO : companySystemList) {
                if (idSet.contains(companySystemDO.getId())) {
                    riskService.deleteRisk(employeeDO.getId(), RISK_ID, companySystemDO.getId());
                } else {
                    riskService.addRisk(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel(), companySystemDO.getId());
                }
            }
        }

    }
}
